#!/bin/bash

# Define color codes
GREEN='\033[0;32m'
RED='\033[0;31m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Navigate to Rust project directory
cd Output/algorithms

echo -e "\n${BLUE}=== Compilation Status ===${NC}"
# Initialize associative array to store compile status
declare -A compile_status

# Define function to compile source files
compile_source_file() {
    local src_file="$1"
    local module_name
    module_name=$(basename "$src_file" .rs)

    if [ "$SHOW_ERRORS" = true ]; then
        if rustc --crate-type lib "$src_file"; then
            echo -e "${GREEN}✓ $src_file compiled successfully${NC}"
            compile_status["$module_name"]=true
        else
            echo -e "${RED}✗ $src_file failed to compile${NC}"
            compile_status["$module_name"]=false
        fi
    else
        if rustc --crate-type lib "$src_file" 2>/dev/null; then
            echo -e "${GREEN}✓ $src_file compiled successfully${NC}"
            compile_status["$module_name"]=true
        else
            echo -e "${RED}✗ $src_file failed to compile${NC}"
            compile_status["$module_name"]=false
        fi
    fi
}

# Compile all source files in src/
echo -e "\n${YELLOW}Compiling source files...${NC}"
for src_file in src/*.rs; do
    # Skip lib.rs as it will be auto-generated
    if [ "$(basename "$src_file")" = "lib.rs" ]; then
        continue
    fi
    compile_source_file "$src_file"
done

# Compile all test files in tests/, only keeping successfully compiled tests
echo -e "\n${YELLOW}Compiling test files...${NC}"
mkdir -p tests_backup
for test_file in tests/*.rs; do
    if [ ! -e "$test_file" ]; then
        echo -e "${YELLOW}No test files matching '*_test.rs' pattern found.${NC}"
        break
    fi

    test_module_name=$(basename "$test_file" .rs)
    if [ "$SHOW_ERRORS" = true ]; then
        if rustc --test "$test_file"; then
            echo -e "${GREEN}✓ $test_file compiled successfully${NC}"
            # Keep the test file
        else
            echo -e "${RED}✗ $test_file failed to compile${NC}"
            # Move failed test file to backup
            mv "$test_file" tests_backup/
        fi
    else
        if rustc --test "$test_file" 2>/dev/null; then
            echo -e "${GREEN}✓ $test_file compiled successfully${NC}"
            # Keep the test file
        else
            echo -e "${RED}✗ $test_file failed to compile${NC}"
            # Move failed test file to backup
            mv "$test_file" tests_backup/
        fi
    fi
done

# Update src/lib.rs to include only successfully compiled non-test modules
echo -e "\n${YELLOW}Updating src/lib.rs with successfully compiled modules...${NC}"
{
    echo "// Auto-generated by the script"
    echo "// Do not edit manually"
    echo ""
} > src/lib.rs

# Exclude failed modules and test modules
for module_name in "${!compile_status[@]}"; do
    if [ "${compile_status[$module_name]}" = true ]; then
        # Exclude test modules and specific modules (e.g., framework)
        if [[ "$module_name" != test_* ]] && [ "$module_name" != "framework" ]; then
            echo "pub mod $module_name;" >> src/lib.rs
        fi
    else
        echo -e "${YELLOW}Skipping module '$module_name' due to compilation failure.${NC}"
    fi
done

# Strengthen compilation checks using cargo check for the entire project
echo -e "\n${BLUE}=== Running cargo check for enhanced compilation verification ===${NC}"
if cargo check; then
    echo -e "${GREEN}cargo check completed successfully.${NC}"
else
    echo -e "${YELLOW}cargo check encountered issues.${NC}"
    # Continue but notify the user
fi

# Run only successfully compiled tests
echo -e "\n${BLUE}=== Running tests for successfully compiled modules ===${NC}"
test_output=$(cargo test --no-fail-fast 2>&1)

# Extract test results
successful_tests=$(echo "$test_output" | grep -o '[0-9]\+ passed' | awk '{sum += $1} END {print sum}')
failed_tests=$(echo "$test_output" | grep -o '[0-9]\+ failed' | awk '{sum += $1} END {print sum}')

# Summary
echo -e "\n${GREEN}Summary:${NC}"

# Count successful and failed compilations
successful_compilations=0
failed_compilations=0
for status in "${compile_status[@]}"; do
    if [ "$status" = true ]; then
        successful_compilations=$((successful_compilations + 1))
    else
        failed_compilations=$((failed_compilations + 1))
    fi
done

echo -e "${GREEN}$successful_compilations files compiled successfully, $failed_compilations files did not compile.${NC}"
echo -e "${GREEN}$successful_tests tests passed, $failed_tests tests did not pass.${NC}"

echo -e "\n${GREEN}All done!${NC}"
